import ipaddress
import struct

import errorhandle
from tools.tools import fmt_mac_addr

INFO_PACKAGE_LENGTH = 27
INFO_HEADER = b')\x00\x01\x00\x01'
INFO_MAC = len(INFO_HEADER) + 6
INFO_IP = INFO_MAC + 4
INFO_UNKWON = INFO_IP + 1
INFO_ADC_BITS = INFO_UNKWON + 1
INFO_UNKWON_REST = INFO_PACKAGE_LENGTH - INFO_ADC_BITS

INSTRUCT_HEADER = b'(\x00\x01\x00\x02'
DATA_HEADER = b')\x00\x01\x00\x02'

DATA_PACKAGE_LENGTH = 1025


# b')\x00\x01\x00\x01\x00\n5\x00\x01\x02\xc0\xa8\x01\x0b\x01\x10\x02\x01\x00\x03\r@\x00\x00\xff\x00'
def parse_info(info):
    if len(info) != INFO_PACKAGE_LENGTH:
        return errorhandle.DATA_LENGTH_EXCEPTION
    if info[0:len(INFO_HEADER)] != INFO_HEADER:
        return errorhandle.DATA_HEADER_EXCEPTION

    macRaw = info[len(INFO_HEADER):INFO_MAC]
    mac = fmt_mac_addr(macRaw.hex())

    ipRaw = info[INFO_MAC:INFO_IP]
    ip = ''
    for ele in ipRaw:
        ip = ip + str(int(ele)) + '.'
    ip = ip[0:-1]
    try:
        ipaddress.ip_address(ip)
    except Exception as e:
        return errorhandle.DATA_IP_EXCEPTION
    return [macRaw, ipRaw, mac, ip]


def parse_data(data):
    res = []
    if len(data) != DATA_PACKAGE_LENGTH:
        return errorhandle.DATA_LENGTH_EXCEPTION
    if data[0:len(DATA_HEADER)] != DATA_HEADER:
        return errorhandle.DATA_HEADER_EXCEPTION
    for i in range(len(DATA_HEADER), len(data)):
        if data[i] == 255 and data[i + 1] == 255:
            data = data[i:]
            break
    for i in range(0, len(data)):
        if i * 10 + 10 < len(data):
            if data[i * 10:i * 10 + 2] == b'\xff\xff':
                singleData = struct.unpack('>%dh' % 4, data[i * 10 + 2:i * 10 + 10])
                res.append(singleData)
    return res


def parse_parameters(settings, mac, isReset=False):
    unknownPara = b'\x00\x00\x00\x01'
    param = INSTRUCT_HEADER + mac + unknownPara
    sampleLen = struct.pack('>i', int(settings['SAMPLE_LEN'], 16))
    initFreq = struct.pack('>i', settings['INIT_FREQ'])
    endFreq = struct.pack('>i', settings['END_FREQ'])
    freqPts = struct.pack('>i', settings['FREQ_PTS'])
    sgFreqTime = struct.pack('>i', settings['SINGLE_FREQ_TIMER'])
    freqDiff = struct.pack('>i', settings['FREQ_DIFF'])
    pulseTime = struct.pack('>i', settings['IMPULSE_TIMER'])
    sgFreqInterval = struct.pack('>f', settings['SINGLE_FREQ_INTERVAL'])
    if isReset:
        start = struct.pack('>B', 0x10)  # 0x10 复位
    else:
        start = struct.pack('>B', 0x11)  # 0x11 开始
    filterPipe = struct.pack('>B', settings['FILTER_PIPE'])
    param = param + sampleLen + initFreq + endFreq + freqPts + \
            sgFreqTime + freqDiff + pulseTime + sgFreqInterval + start + filterPipe
    return param
